﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Web;
using AWS.SLAM.Configuration;
using System.Text.RegularExpressions;

using System.ComponentModel;

using Microsoft.SharePoint;
using AWS.SLAM.Logging;

namespace AWS.SLAM.SharePoint
{
    public static class SPListItemExtender
    {
        public static string GetTitle(this SPListItem listItem)
        {
            string title = "";
            if (listItem.Fields.ContainsField("Title"))
            {
                title = listItem.Title;
            }
            else if (listItem.Fields.ContainsField("Name"))
            {
                title = (string)listItem["Name"];
            } 
            else 
            {
                title = listItem.Name;
            }

            return title;
        }

        public static Hashtable GetFieldValues(this SPListItem listItem, List<Field> outputFields)
        {
            Hashtable values = new Hashtable();
            values.Add("ListItemID", listItem.UniqueId);
            values.Add("ListID", listItem.ParentList.ID);
            values.Add("ListRelativeID", listItem.ID);

            foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(listItem))
            {
                Field currentField = outputFields.Find(delegate(Field fieldToMatch) { return fieldToMatch.Name == property.Name; });

                //if (currentField != null && !String.IsNullOrEmpty(currentField.Name) && !listItem.Fields.ContainsField(property.Name))
                if (currentField != null && !String.IsNullOrEmpty(currentField.Name))
                {
                    if (!values.ContainsKey(GetColumnName(currentField)))
                    {
                        values.Add(GetColumnName(currentField), property.GetValue(listItem) == null ? "" : property.GetValue(listItem).ToString());
                    }
                }
            }

            foreach (SPField field in listItem.Fields)
            {
                Field currentField = outputFields.Find(delegate(Field fieldToMatch) { return fieldToMatch.Name == field.InternalName || fieldToMatch.Name == field.Title; });

                if (currentField != null && !String.IsNullOrEmpty(currentField.Name))
                {
                    try
                    {
                        if (!values.ContainsKey(GetColumnName(currentField)))
                        {
                            values.Add(GetColumnName(currentField), listItem[field.Id] == null ? "" : listItem[field.Id].ToString());
                        }
                    }
                    catch(Exception ex)
                    {
                        ILogger logger = ComponentService.GetInstance<ILogger>();
                        logger.LogMessage("Exception", String.Format("The given ListItem is reporting to have the field: {0}, but its value is inaccessible.{1}Matched Display Name: {2}{1}Matched Internal Name: {3}{1}Matched Field ID: {4}{1}Exception:{5}", currentField.Name, Environment.NewLine, field.Title, field.InternalName, field.Id.ToString(), ex.ToString()));
                    }
                }
            }

            return values;
        }

        private static string GetColumnName(Field field)
        {
            string columnName = field.Name;
            if (field is SqlMappedField)
            {
                SqlMappedField sqlField = (SqlMappedField)field;
                columnName = String.IsNullOrEmpty(sqlField.Column) ? Regex.Replace(field.Name, "[\\W\\s]", "") : sqlField.Column;
            }
            return columnName;
        }
    }
}
